﻿#region ... Copyright Notice ...
/*
   Copyright 2008 Tyler Jensen

	Author: Tyler Jensen    http://www.tsjensen.com/blog

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
#endregion

using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml.Linq;
using Atrax.Contracts;
using Atrax.Library;
using Atrax.Logging;
using Atrax.Security;

namespace Atrax.Master
{
	internal class CallbackSender
	{
		internal void SendCallback(QueryResult result)
		{
			//Log.Debug(string.Format("AtraxCallbackSender.SendCallback called for {0}", jobData.JobId));
			//This sends a standard HTTP POST callback to the original caller of the job
			System.Net.WebRequest req = null;
			System.Net.WebResponse resp = null;
			try
			{
				string authCode = GetReturnAuthCode(result.Query.Header);

				string postData = "queryid=" + HttpUtility.UrlEncode(result.Query.Header.QueryId)
					+ "&clientqueryid=" + HttpUtility.UrlEncode(result.Query.Header.ClientQueryId)
					+ "&querytype=" + HttpUtility.UrlEncode(result.Query.Header.QueryType)
					+ "&authcode=" + HttpUtility.UrlEncode(authCode)
					+ "&statuscode=" + HttpUtility.UrlEncode(result.StatusCode)
					+ "&statusdescription=" + HttpUtility.UrlEncode(result.Result)
					+ "&resultschema=" + HttpUtility.UrlEncode(result.ResultSchema)
					+ "&result=" + HttpUtility.UrlEncode(result.Result);

				req = System.Net.WebRequest.Create(result.Query.Header.CallbackUrl);
				req.Method = "POST";
				req.Timeout = 180000;  //in milliseconds 180 seconds

				req.ContentType = ConfigurationManager.AppSettings["callbackContentType"];
				byte[] data = Encoding.UTF8.GetBytes(postData); //xml should be UTF8

				// Set the content length of the string being posted.
				//from MSDN docs: Note - You must set the value of the ContentLength property before retrieving the stream.
				req.ContentLength = data.Length;

				Stream up = null;
				try
				{
					up = req.GetRequestStream();
					up.Write(data, 0, data.Length);
				}
				catch (Exception inner)
				{
					throw inner;
				}
				finally
				{
					if (up != null) up.Close();
				}

				string httpResponse = string.Empty;
				resp = req.GetResponse();
				Stream s = null;
				StreamReader sr = null;
				try
				{
					s = resp.GetResponseStream();
					sr = new StreamReader(s);
					httpResponse = sr.ReadToEnd();
				}
				catch (Exception inresp)
				{
					throw inresp;
				}
				finally
				{
					if (sr != null) sr.Close();
					if (s != null) s.Close();
				}

				//log success of callback for records
				Log.App(LogEvents.CallbackSenderSucceeded, "queryid=" + result.Query.Header.QueryId
					+ " | querytype=" + result.Query.Header.QueryType + " | licensekey=" + result.Query.Header.LicenseKey);
			}
			catch (Exception e)
			{
				Log.App(LogEvents.CallbackSenderFailed, "queryid=" + result.Query.Header.QueryId
					+ " | querytype=" + result.Query.Header.QueryType + " | licensekey=" + result.Query.Header.LicenseKey, e);
				//now try to email the response
				Emailer em = new Emailer();
				em.SendCallbackFailureNotification(result, e);
			}
			finally
			{
				if (resp != null) resp.Close();
			}
		}

		private string GetReturnAuthCode(QueryHeader queryHeader)
		{
			KeyManager km = new KeyManager();
			string code = km.CreateReturnAuthCode(queryHeader.LicenseKey, queryHeader.QueryId, queryHeader.ClientQueryId, queryHeader.QueryType);
			return code;
		}
	}
}
